/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package dao;

import java.util.HashSet;
import java.util.List;
import org.hibernate.Query;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import pojo.Binhluan;
import pojo.Sanpham;
import pojo.Tinhtrang;
import util.HibernateUtil;

/**
 *
 * @author kydrenw
 */
public class SanphamDAO {

    /**
     * Lấy thông tin sản phẩm theo mã sản phẩm.
     * @param maSP : mã sản phầm cần lấy thông tin.
     * @return Nếu tìm thấy --> đối tượng chứa thông tin sản phẩm.
     * Null nếu không tìm thấy.
     */
    public static Sanpham layThongTin(int maSP) {
        Session session = HibernateUtil.getSessionFactory().getCurrentSession();
        session.beginTransaction();
        Sanpham sp = (Sanpham) session.get(Sanpham.class, maSP);

        if (sp != null) {
            List<Binhluan> bl = BinhluanDAO.layDanhSach(maSP);
            if (bl != null) {
                sp.setBinhluans(new HashSet(bl));
            } else {
                sp.setBinhluans(null);
            }
        }

        return sp;
    }

    /**
     * Lấy danh sách các sản phẩm hiện có.
     * @return danh sách chứa thông tin các sản phẩm hiện có.
     */
    public static List<Sanpham> layDanhSach() {
        List<Sanpham> ds;

        try {
            Session session = HibernateUtil.getSessionFactory().getCurrentSession();
            session.beginTransaction();
            String hql = "FROM Sanpham ";
            Query query = session.createQuery(hql);
            ds = query.list();
        } catch (Exception ex) {
            ds = null;
        }

        return ds;
    }

    /**
     * Lấy danh sách các sản phẩm có giới hạn số lượng.
     * @param soSP : số lượng tối đa các sản phẩm cần lấy
     * @return danh sách chứa thông tin các sản phẩm hiện có, null nếu không tìm thấy.
     */
    public static List<Sanpham> layDanhSach(int soSP) {
        List<Sanpham> result = null;
        SessionFactory sf = HibernateUtil.getSessionFactory();
        Session session = sf.getCurrentSession();
        Transaction trans = session.getTransaction();
        String hql = "From Sanpham";

        try {
            trans.begin();
            Query qr = session.createQuery(hql);
            qr.setFirstResult(0);
            qr.setMaxResults(soSP);
            result = qr.list();
            trans.commit();

        } catch (Exception ex) {
        }
        return result;
    }

    /**
     * Thêm sản phẩm mới vào CSDL
     * @param sp: đối tượng chứa thông tin sản phẩm cần thêm vào.
     * @return true nếu thêm thành công, false nếu thất bại.
     */
    public static boolean themSanPham(Sanpham sp) {

        Session session = HibernateUtil.getSessionFactory().getCurrentSession();
        try {
            session.beginTransaction();
            session.saveOrUpdate(sp);
            session.getTransaction().commit();
            return true;

        } catch (Exception e) {
            session.getTransaction().rollback();
            System.out.println(e);
            return false;
        }
    }

    /**
     * Đánh dấu trong csdl là sản phẩm đã được xóa.
     * @param masp : mã sản phẩm cần xóa.
     * @return true nếu thành công, false nếu thất bại.
     */
    public static boolean xoaSanPham(int masp) {
        Sanpham sp = SanphamDAO.layThongTin(masp);
        if (sp == null) {
            return false;
        }
        //6 : đã xóa
        int matt = 6;
        Tinhtrang tt = TinhtrangDAO.layThongTin(matt);
        sp.setTinhtrang(tt);
        Session session = HibernateUtil.getSessionFactory().getCurrentSession();

        try {
            session.beginTransaction();
            session.saveOrUpdate(sp);
            session.flush();
            session.getTransaction().commit();
            return true;

        } catch (Exception e) {
            session.getTransaction().rollback();
            System.out.println(e);
            return false;
        }
    }

    /**
     * cập nhật thông tin sản phẩm.
     * @param sp : Thông tin sản phẩm cần cập nhật.
     * @return true nếu thành công, fals nếu thất bại.
     */
    public static boolean suaSanPham(Sanpham sp) {
        if (SanphamDAO.layThongTin(sp.getMasp()) == null) {
            return false;
        }
        Session session = HibernateUtil.getSessionFactory().getCurrentSession();
        try {

            session.beginTransaction();
            session.saveOrUpdate(sp);
            session.flush();
            session.getTransaction().commit();
            return true;

        } catch (Exception e) {
            session.getTransaction().rollback();
            System.out.println(e);
            return false;
        }
    }

    /**
     * Tìm kiếm sản phẩm theo từ khóa hoăc/ và theo danh mục.
     * @param tukhoa : từ khóa có liên quan.
     * @param danhmuc : mã danh mục sản phẩm cần tìm.
     * @return : danh sách sản phẩm tìm thấy, nếu không, trả về null.
     */
    public static List<Sanpham> timKiem(String tukhoa, int danhmuc) {

        String hql = null;
        List<Sanpham> ds;
        if (danhmuc == 1) {
            hql = "from Sanpham where tensp like :tukhoa and tinhtrang.ma<>6 and tinhtrang.ma<>0";
        } else if (danhmuc == 2) {
            hql = "from Sanpham where loaisp.ten like :tukhoa and tinhtrang.ma<>6 and tinhtrang.ma<>0";
        } else if (danhmuc == 3) {
            hql = "from Sanpham where mota like :tukhoa and tinhtrang.ma<>6 and tinhtrang.ma<>0";
        }
        try {

            Session session = HibernateUtil.getSessionFactory().getCurrentSession();
            session.beginTransaction();
            Query query = session.createQuery(hql);
            query.setString("tukhoa", "%" + tukhoa + "%");
            ds = query.list();

        } catch (Exception ex) {
            ds = null;
        }


        return ds;
    }

    /**
     * Lấy danh sách sản phẩm mới nhập vào.
     * @param soSanPham: số lượng sản phẩm tối đa.
     * @return : danh sách các sản phẩm mới nhất được tìm thấy, nếu không, trả
     * về null.
     */
    public static List<Sanpham> laySanPhamMoiNhat(int soSanPham) {

        List<Sanpham> result = null;
        SessionFactory sf = HibernateUtil.getSessionFactory();
        Session session = sf.getCurrentSession();
        Transaction trans = session.getTransaction();
        String hql = "from Sanpham sp order by sp.ngaydang desc";

        try {
            trans.begin();
            Query qr = session.createQuery(hql);
            qr.setFirstResult(0);
            qr.setMaxResults(soSanPham);
            result = qr.list();
            trans.commit();

        } catch (Exception ex) {
            trans.rollback();
            System.out.println(ex.getMessage());
            result = null;
        }

        return result;
    }

    /**
     * Lấy danh sách sản phẩm theo loại sản phẩm.
     * @param maLoai: mã loại sản phẩm cần lấy danh sách sản phẩm.
     * @param trang: trang sản phẩm cần lấy (dùng trong phân trang).
     * @param soSanPham : số sản phẩm tối đa cần lấy.
     * @return Danh sách sản phẩm tìm thấy, nếu không, trả về null.
     */
    public static List<Sanpham> laySanPhamTheoLoai(int maLoai, int trang, int soSanPham) {

        List<Sanpham> result = null;
        SessionFactory sf = HibernateUtil.getSessionFactory();
        Session session = sf.getCurrentSession();
        Transaction trans = session.getTransaction();
        String hql = "from Sanpham sp where sp.loaisp.ma =:Ma";

        try {
            trans.begin();
            Query qr = session.createQuery(hql);
            qr.setInteger("Ma", maLoai);
            if (trang != -1) {
                qr.setFirstResult(trang * soSanPham);
            }
            if (soSanPham != -1) {
                qr.setMaxResults(soSanPham);
            }
            result = qr.list();
            trans.commit();

        } catch (Exception ex) {
            trans.rollback();
            System.out.println(ex.getMessage());
            result = null;
        }

        return result;
    }

    /**
     * Lấy số lượng sản phẩm theo mã loại sản phẩm.
     * @param maLoai : mã loại sản phẩm cần đếm số lượng.
     * @return số lượng sản phẩm đếm được.
     */
    public static int laySoSanPhamTheoLoai(int maLoai) {

        int result = 0;
        SessionFactory sf = HibernateUtil.getSessionFactory();
        Session session = sf.getCurrentSession();
        Transaction trans = session.getTransaction();
        String hql = " select count(sp.masp) from Sanpham sp where sp.loaisp.ma =:Ma";

        try {
            trans.begin();
            Query qr = session.createQuery(hql);
            qr.setInteger("Ma", maLoai);
            result = Integer.parseInt(qr.list().get(0).toString());
            trans.commit();

        } catch (Exception ex) {
            trans.rollback();
            System.out.println(ex.getMessage());
            result = 0;
        }
        return result;
    }

    /**
     * Tìm kiếm danh sách sản phẩm theo 1 số thông tin đơn giản.
     * @param input : thông tin để tìm kiếm.
     * @param trang : trang sản phẩm cần lấy (dùng trong phân trang).
     * @param soSanPham : Số lượng sản phẩm tối đa cần lấy.
     * @return : danh sách sản phẩm tìm thấy, nếu không, trả về null.
     */
    public static List<Sanpham> timDonGian(String input, int trang, int soSanPham) {

        List<Sanpham> result = null;
        SessionFactory sf = HibernateUtil.getSessionFactory();
        Session session = sf.getCurrentSession();
        Transaction trans = session.getTransaction();
        String hql = "from Sanpham sp where sp.tensp like :Ten";

        try {
            trans.begin();
            Query qr = session.createQuery(hql);
            qr.setString("Ten", "%" + input + "%");
            qr.setFirstResult(trang * soSanPham);
            qr.setMaxResults(soSanPham);
            result = qr.list();
            trans.commit();

        } catch (Exception ex) {
            trans.rollback();
            System.out.println(ex.getMessage());
            result = null;
        }

        return result;
    }

    /**
     * Đếm số sản phẩm tìm thấy trong tìm kiếm đơn giản.
     * @param input: thông tin cho tìm kiếm.
     * @return : số lượng sản phẩm tìm thấy theo thông tin đưa vào.
     */
    public static int laySoSanPhamDonGian(String input) {

        int result = 0;
        SessionFactory sf = HibernateUtil.getSessionFactory();
        Session session = sf.getCurrentSession();
        Transaction trans = session.getTransaction();
        String hql = " select count(sp.masp) from Sanpham sp where sp.tensp like :Ten";

        try {
            trans.begin();
            Query qr = session.createQuery(hql);
            qr.setString("Ten", "%" + input + "%");
            result = Integer.parseInt(qr.list().get(0).toString());
            trans.commit();

        } catch (Exception ex) {
            trans.rollback();
            System.out.println(ex.getMessage());
            result = 0;
        }
        return result;
    }

    /**
     * Tìm kiếm sản phẩm nâng cao.
     * @param input: từ khóa có liên quan đến sản phẩm.
     * @param danhMuc: danh mục mà sản phẩm thuộc về.
     * @param danhMucCon : Danh mục nhỏ mà sản phẩm đó thuộc về.
     * @param gia: mức giá cần tìm.
     * @param trang : trang sản phẩm (trong phân trang).
     * @param soSanPham : Số sản phẩm tối đa cần lấy.
     * @return : danh sachs sản phẩm tìm thấy, null nếu không tìm thấy.
     */
    public static List<Sanpham> timNangCao(String input, int danhMuc, int danhMucCon, int gia, int trang, int soSanPham) {

        List<Sanpham> result = null;
        SessionFactory sf = HibernateUtil.getSessionFactory();
        Session session = sf.getCurrentSession();
        Transaction trans = session.getTransaction();
        String hql = "from Sanpham sp where 1=1 ";

        if (input != null) {
            hql += "and sp.tensp like :Ten ";
        }
        if (danhMucCon > 0) {
            hql += "and sp.loaisp.ma =:dmCon ";
        }
        if (danhMuc > 0) {
            hql += "and sp.loaisp.danhmuc.ma =:dmChinh ";
        }
        if (gia > 0) {
            switch (gia) {
                case 50:
                    hql += " and sp.gia < 50 ";
                    break;
                case 100:
                    hql += " and sp.gia < 100 and sp.gia > 50";
                    break;
                case 200:
                    hql += " and sp.gia < 200 and sp.gia > 100";
                    break;
                case 500:
                    hql += " and sp.gia < 500 and sp.gia > 200";
                    break;
                case 1000:
                    hql += " and sp.gia < 1000 and sp.gia > 500";
                    break;
                case 1500:
                    hql += " and sp.gia < 1500 and sp.gia > 1000";
                    break;
                case 2000:
                    hql += " and sp.gia < 2000 and sp.gia > 1500";
                    break;
                case 2001:
                    hql += " and sp.gia > 2000";
                    break;
            }
        }
        try {
            trans.begin();
            Query qr = session.createQuery(hql);

            // Set gia trị cho các tham số nếu đối số hợp lệ
            if (input != null) {
                qr.setString("Ten", "%" + input + "%");
            }
            if (danhMucCon > 0) {
                qr.setInteger("dmCon", danhMucCon);
            }
            if (danhMuc > 0) {
                qr.setInteger("dmChinh", danhMuc);
            }

            qr.setFirstResult(trang * soSanPham);
            qr.setMaxResults(soSanPham);
            result = qr.list();
            trans.commit();

        } catch (Exception ex) {
            trans.rollback();
            System.out.println(ex.getMessage());
            result = null;
        }

        return result;
    }

    /**
     * Đếm số lượng sản phẩm tìm thấy trong tìm kiếm sản phẩm nâng cao.
     * @param input: từ khóa có liên quan đến sản phẩm.
     * @param danhMuc: danh mục mà sản phẩm thuộc về.
     * @param danhMucCon : Danh mục nhỏ mà sản phẩm đó thuộc về.
     * @param gia: mức giá cần tìm.
     * @return : số sản phẩm tìm thấy.
     */
    public static int laySoSanPhamNangCao(String input, int danhMuc, int danhMucCon, int gia) {
        int result = 0;
        SessionFactory sf = HibernateUtil.getSessionFactory();
        Session session = sf.getCurrentSession();
        Transaction trans = session.getTransaction();
        String hql = "select count(sp.masp) from Sanpham sp where 1=1 ";

        // xét các đôi số truyền vào, nếu hợp lệ thì thêm vào câu truy vấn.
        if (input != null) {
            hql += "and sp.tensp like :Ten ";
        }
        if (danhMucCon > 0) {
            hql += "and sp.loaisp.ma =:dmCon ";
        }
        if (danhMuc > 0) {
            hql += "and sp.loaisp.danhmuc.ma =:dmChinh ";
        }

        // Xét khoảng giá đưa vào.
        if (gia > 0) {
            switch (gia) {
                case 50:
                    hql += " and sp.gia < 50 ";
                    break;
                case 100:
                    hql += " and sp.gia < 100 and sp.gia > 50";
                    break;
                case 200:
                    hql += " and sp.gia < 200 and sp.gia > 100";
                    break;
                case 500:
                    hql += " and sp.gia < 500 and sp.gia > 200";
                    break;
                case 1000:
                    hql += " and sp.gia < 1000 and sp.gia > 500";
                    break;
                case 1500:
                    hql += " and sp.gia < 1500 and sp.gia > 1000";
                    break;
                case 2000:
                    hql += " and sp.gia < 2000 and sp.gia > 1500";
                    break;
                case 2001:
                    hql += " and sp.gia > 2000";
                    break;
            }
        }
        try {
            trans.begin();
            Query qr = session.createQuery(hql);

            // set gia trị cho các tham số nếu các đối số hợp lệ.
            if (input != null) {
                qr.setString("Ten", "%" + input + "%");
            }
            if (danhMucCon > 0) {
                qr.setInteger("dmCon", danhMucCon);
            }
            if (danhMuc > 0) {
                qr.setInteger("dmChinh", danhMuc);
            }

            result = Integer.parseInt(qr.list().get(0).toString());
            trans.commit();

        } catch (Exception ex) {
            trans.rollback();
            System.out.println(ex.getMessage());
            result = 0;
        }

        return result;
    }

    /**
     * Lấy danh sách sản phẩm có số lượng bán nhiều nhất.
     * @param soSP : số sản phẩm tối đa cần lấy.
     * @return : Danh sách sản phẩm tìm thấy.
     */
    public static List<Object[]> laySanPhamBanChay(int soSP) {
        List<Object[]> result = null;
        SessionFactory sf = HibernateUtil.getSessionFactory();
        Session session = sf.getCurrentSession();
        Transaction trans = session.getTransaction();
        String sql = "SELECT sp.masp, tensp, sum(soluong) as soluongban "
                + "FROM Chitiethoadon as ct, Sanpham as sp "
                + "where ct.masp=sp.masp "
                + "group by sp.masp "
                + "order by soluongban desc";

        try {
            trans.begin();
            Query qr = session.createSQLQuery(sql);
            qr.setFirstResult(0);
            if (soSP != -1) {
                qr.setMaxResults(soSP);
            }
            result = qr.list();
            trans.commit();
        } catch (Exception ex) {
        }
        return result;
    }

    /**
     * Lấy danh sách sản phẩm có số lượng bán ra nhiều nhất trong vòng 30 ngày 
     * kể từ ngày hiện tại.
     * @param soSanPham Số sản phẩm tối đa cần lấy.
     * @return : danh sách sản phẩm tìm thấy, nếu không, trả về null.
     */
    public static List<Sanpham> laySanPhamBanChayD(int soSanPham) {
        List<Sanpham> result = null;
        SessionFactory sf = HibernateUtil.getSessionFactory();
        Session session = sf.getCurrentSession();
        Transaction trans = session.getTransaction();
        String hql = "Call LaySanPhamBanChay(:soSanPham)";

        try {
            trans.begin();

            // Gọi procedure của MySql. Set class của đối tượng trả về
            Query qr = session.createSQLQuery(hql).addEntity(Sanpham.class);
            qr.setInteger("soSanPham", soSanPham);
            result = qr.list();
            trans.commit();

        } catch (Exception ex) {
            System.out.println(ex.getMessage());
            result = null;
        }
        return result;
    }

    /**
     * Lấy danh sách sản phẩm có doanh thu lớn nhất
     * @param soSanPham Số sản phẩm tối đa cần lấy.
     * @return : danh sách sản phẩm tìm thấy, nếu không, trả về null.
     */
    public static List<Object[]> laySanPhamDoanhThuLon(int soSP) {
        List<Object[]> result = null;
        SessionFactory sf = HibernateUtil.getSessionFactory();
        Session session = sf.getCurrentSession();
        Transaction trans = session.getTransaction();
        String sql = "SELECT sp.masp, tensp, sum(soluong*dongia) as doanhthu "
                + "FROM Chitiethoadon as ct, Sanpham as sp "
                + "where ct.masp=sp.masp "
                + "group by sp.masp "
                + "order by doanhthu desc";

        try {
            trans.begin();
            Query qr = session.createSQLQuery(sql);
            qr.setFirstResult(0);
            if (soSP != -1) {
                qr.setMaxResults(soSP);
            }
            result = qr.list();
            trans.commit();
        } catch (Exception ex) {
        }
        return result;
    }
}
